from django.http import JsonResponse

# 导入medicine对象定义
from common.models import Medicine

from django.db.models import Q
# 增加对分页的支持
from django.core.paginator import Paginator, EmptyPage

import traceback
import json
from config import settings
from django_redis import get_redis_connection

# def dispatcher(request):
#     # 根据session判断用户是否登录的管理员用户
#     if 'usertype' not in request.session:
#         return JsonResponse({
#             'ret': 302,
#             'msg': '未登录',
#             'redirect': '/mgr/sign.html'
#         },
#         status = 302
#         )
    
#     if request.session['usertype'] != 'mgr':
#         return JsonResponse({
#             'ret': 302,
#             'msg': '非mgr用户',
#             'redirect': '/mgr/sign.html' 
#         },
#         status = 302
#         )
    
#     # 将请求参数统一放入request的prams属性中,方便后续处理
#     # get请求参数在request对象的get属性中
#     if request.method == 'GET':
#         request.params = request.GET
#     # post/put/delete请求参数从request对象的body属性中获取
#     elif request.method in ['POST', 'PUT', 'DELETE']:
#         # 根据接口,post/put/delete请求的消息体都是json格式
#         request.params = json.loads(request.body)

#     # 根据不同的action分派给不同的函数处理
#     action = request.params['action']
#     if action == 'list_medicine':
#         return listmedicine(request)
#     elif action == 'add_medicine':
#         return addmedicine(request)
#     elif action == 'modify_medicine':
#         return modifymedicine(request)
#     elif action == 'del_medicine':
#         return deletemedicine(request)
    
#     else:
#         return JsonResponse({'ret': 1, 'msg': '不支持该类型的http请求'})
    
# def listmedicine(request):
#     # 返回一个queryset对象,包含所有表的记录
#     qs = Medicine.objects.values()

#     # 将queryset对象转化为list类型,否则不能被转化为json字符串
#     retlist = list(qs)

#     return JsonResponse({'ret': 0, 'retlist': retlist})

# 获取一个和redis服务的连接
rconn = get_redis_connection("default")
def listmedicine(request):
    try:
        # 查看是否有关键字搜索参数
        keywords = request.params.get('keywords', None)
        # 要获取的第几页
        pagenum = request.params['pagenum']
        # 每页要显示多少条记录
        pagesize = request.params['pagesize']

        # 先查看缓存中是否有
        cacheFiled = f'{pagesize}|{pagenum}|{keywords}' # 缓存filed

        cacheObj = rconn.hget(settings.CK.MedineList,
                              cacheFiled)
        
        # 缓存中有，需要反序列化
        if cacheObj:
            print('缓存命中')
            retObj = json.loads(cacheObj)
        # 如果缓存中没有，再去数据库中查询
        else:
            print('缓存中没有')
            # 返回一个queryset对象，包含所有表的记录
            # .order_by('-id')表示按照id字段的值倒序排列
            # 这样可以保证最新的记录显示在最前面
            qs = Medicine.objects.values().order_by('-id')

            # # 查看是否有关键字搜索参数
            # keywords = request.params.get('keywords', None)
            if keywords:
                conditions = [Q(name__contains=one) for one in keywords.split(' ') if one]
                query = Q()
                for condition in conditions:
                    query &= condition
                qs = qs.filter(query)

            # # 要获取的第几页
            # pagenum = request.params['pagenum']
            
            # # 每页要显示多少条记录
            # pagesize = request.params['pagesize']

            # 使用分页对象，设定每页多少条记录
            pgnt = Paginator(qs, pagesize)

            # 从数据库中读取数据,指定读取其中第几页
            page = pgnt.page(pagenum)

            # 将queryset对象转化为list类型
            retlist = list(page)

            retObj = {'ret': 0, 'retlist': retlist, 'total': pgnt.count}

            # 存入缓存
            rconn.hset(settings.CK.MedineList,
                       cacheFiled,
                       json.dumps(retObj))

        # total指定了一共有多少条数据
        return JsonResponse(retObj)
        # return JsonResponse({'ret': 0, 'retlist': retlist, 'total': pgnt.count})
    except EmptyPage:
        return JsonResponse({'ret': 0, 'retlist': [], 'total': 0})
    except:
         return JsonResponse({'ret': 2, 'msg': f'未知错误\n{traceback.format_exc()}'})

def addmedicine(request):
    info = request.params['data']
    # 从请求消息中获取要添加的用户信息
    # 并且插入到数据库中
    medicine = Medicine.objects.create(name = info['name'],
                                       sn = info['sn'],
                                       desc = info['desc'])
    
    # 同时删除整个medicine缓存数据
    # 因为不知道这个添加的药品会影响到哪些列出的结果
    # 只能全部删除
    rconn.delete(settings.CK.MedineList)

    return JsonResponse({'ret': 0, 'id': medicine.id})

def modifymedicine(request):

    # 从请求消息中获取要修改客户的信息
    # 找到该客户并进行修改操作
    medicineid = request.params['id']
    newdata = request.params['newdata']

    try:
        # 根据id从数据库中找到相应的客户记录
        medicine = Medicine.objects.get(id = medicineid)
    except Medicine.DoesNotExist:
        return {
            'ret': 1,
            'msg': f'id为{medicineid}的药品不存在'
        }
    if 'name' in newdata:
        medicine.name = newdata['name']
    if 'sn' in newdata:
        medicine.sn = newdata['sn']
    if 'desc' in newdata:
        medicine.desc = newdata['desc']

    # 一定要执行save才能将修改信息保存到数据库
    medicine.save()

    # 同时删除整个medicine缓存数据
    # 因为不知道这个添加的药品会影响到哪些列出的结果
    # 只能全部删除
    rconn.delete(settings.CK.MedineList)

    return JsonResponse({'ret': 0})

def deletemedicine(request):

    medicineid = request.params['id']

    try:
        # 根据id从数据库中找到相应的药品记录
        medicine = Medicine.objects.get(id = medicineid)
    except Medicine.DoesNotExist:
        return {
            'ret': 1,
            'msg': f'id为{medicineid}的客户不存在'
        }
    # 删除操作
    medicine.delete()
    
    # 同时删除整个medicine缓存数据
    # 因为不知道这个添加的药品会影响到哪些列出的结果
    # 只能全部删除
    rconn.delete(settings.CK.MedineList)

    return JsonResponse({'ret': 0})
# 实现模块后在/mgr/urls.py里面设置路由

from lib.handler import dispatcherBase

Action2Handler = {
    'list_medicine': listmedicine,
    'add_medicine': addmedicine,
    'modify_medicine': modifymedicine,
    'del_medicine': deletemedicine,
}

def dispatcher(request):
    return dispatcherBase(request, Action2Handler)